package com.ozo.cloud.gen.util;

import cn.hutool.core.util.StrUtil;
import com.ozo.cloud.common.base.constant.CommonConstant;

import java.util.HashMap;
import java.util.Map;

/**
 * 代码生成工具类
 *
 * @author qiangesoft
 * @date 2023-09-29
 */
public class CodeGenUtil {

    /**
     * java路径
     */
    public static final String JAVA_PATH = "src" + CommonConstant.SLASH + "main" + CommonConstant.SLASH + "java" + CommonConstant.SLASH;

    /**
     * 资源文件路径
     */
    public static final String RESOURCES_PATH = "src" + CommonConstant.SLASH + "main" + CommonConstant.SLASH + "resources" + CommonConstant.SLASH;

    /**
     * vue表单路径
     */
    public static String VUE_PATH = "src" + CommonConstant.SLASH + "views" + CommonConstant.SLASH;

    /**
     * js代码路径
     */
    public static String JS_PATH = "src" + CommonConstant.SLASH + "api" + CommonConstant.SLASH;


    /**
     * 实体类
     */
    public static String ENTITY = "Entity";

    /**
     * 控制层
     */
    public static String CONTROLLER = "Controller";

    /**
     * 服务层接口
     */
    public static String SERVICE = "Service";

    /**
     * 服务层实现类
     */
    public static String SERVICE_IMPL = "ServiceImpl";

    /**
     * 持久层
     */
    public static String MAPPER = "Mapper";

    /**
     * 持久层xml
     */
    public static String MAPPER_XML = "MapperXML";

    /**
     * 查询对象
     */
    public static String QUERY_DTO = "QueryDTO";

    /**
     * 保存对象
     */
    public static String SAVE_DTO = "SaveDTO";

    /**
     * 查询对象
     */
    public static String VO = "VO";

    /**
     * vue表格页面
     */
    public static String INDEX_VUE = "IndexVue";

    /**
     * vue表单页面
     */
    public static String SAVE_VUE = "SaveVue";

    /**
     * js代码
     */
    public static String JS = "Js";

    /**
     * sql代码
     */
    public static String SQL = "Sql";

    /**
     * 模板文件
     */
    public static final Map<String, String> TEMPLATE_MAP = new HashMap<>();

    /**
     * 模板文件
     */
    static {
        TEMPLATE_MAP.put(ENTITY, "Entity.java.ftl");
        TEMPLATE_MAP.put(MAPPER, "Mapper.java.ftl");
        TEMPLATE_MAP.put(SERVICE, "Service.java.ftl");
        TEMPLATE_MAP.put(SERVICE_IMPL, "ServiceImpl.java.ftl");
        TEMPLATE_MAP.put(CONTROLLER, "Controller.java.ftl");
        TEMPLATE_MAP.put(SAVE_DTO, "SaveDTO.java.ftl");
        TEMPLATE_MAP.put(QUERY_DTO, "QueryDTO.java.ftl");
        TEMPLATE_MAP.put(VO, "VO.java.ftl");
        TEMPLATE_MAP.put(MAPPER_XML, "Mapper.xml.ftl");
        TEMPLATE_MAP.put(INDEX_VUE, "Index.vue.ftl");
        TEMPLATE_MAP.put(SAVE_VUE, "Save.vue.ftl");
        TEMPLATE_MAP.put(JS, "Api.js.ftl");
        TEMPLATE_MAP.put(SQL, "Menu.sql.ftl");
    }

    /**
     * java代码包路径
     */
    public static Map<String, String> javaFilePackage(String genPackage, String genModule) {
        Map<String, String> map = new HashMap<>();
        String packagePath = StrUtil.isNotBlank(genModule) ? genPackage + "." + genModule : genPackage;
        map.put(ENTITY, packagePath + ".entity");
        map.put(CONTROLLER, packagePath + ".controller");
        map.put(SERVICE, packagePath + ".service");
        map.put(SERVICE_IMPL, packagePath + ".service.impl");
        map.put(MAPPER, packagePath + ".mapper");
        map.put(QUERY_DTO, packagePath + ".pojo.dto");
        map.put(SAVE_DTO, packagePath + ".pojo.dto");
        map.put(VO, packagePath + ".pojo.vo");
        return map;
    }

    /**
     * 文件相对路径
     */
    public static Map<String, String> fileRelativePath(String projectCode, String genPackage, String genModule, String genClass, String genClassName, String genBusiness) {
        Map<String, String> javaFilePackageMap = javaFilePackage(genPackage, genModule);

        String moduleName = projectCode + CommonConstant.DELIMITER + genModule + CommonConstant.SLASH;

        Map<String, String> map = new HashMap<>();
        map.put(ENTITY, moduleName + JAVA_PATH + javaFilePackageMap.get(ENTITY).replace(CommonConstant.PERIOD_C, CommonConstant.SLASH_C) + CommonConstant.SLASH + genClass + ".java");
        map.put(CONTROLLER, moduleName + JAVA_PATH + javaFilePackageMap.get(CONTROLLER).replace(CommonConstant.PERIOD_C, CommonConstant.SLASH_C) + CommonConstant.SLASH + genClass + "Controller.java");
        map.put(SERVICE, moduleName + JAVA_PATH + javaFilePackageMap.get(SERVICE).replace(CommonConstant.PERIOD_C, CommonConstant.SLASH_C) + CommonConstant.SLASH + "I" + genClass + "Service.java");
        map.put(SERVICE_IMPL, moduleName + JAVA_PATH + javaFilePackageMap.get(SERVICE_IMPL).replace(CommonConstant.PERIOD_C, CommonConstant.SLASH_C) + CommonConstant.SLASH + genClass + "ServiceImpl.java");
        map.put(MAPPER, moduleName + JAVA_PATH + javaFilePackageMap.get(MAPPER).replace(CommonConstant.PERIOD_C, CommonConstant.SLASH_C) + CommonConstant.SLASH + genClass + "Mapper.java");
        map.put(QUERY_DTO, moduleName + JAVA_PATH + javaFilePackageMap.get(QUERY_DTO).replace(CommonConstant.PERIOD_C, CommonConstant.SLASH_C) + CommonConstant.SLASH + genClass + "QueryDTO.java");
        map.put(SAVE_DTO, moduleName + JAVA_PATH + javaFilePackageMap.get(SAVE_DTO).replace(CommonConstant.PERIOD_C, CommonConstant.SLASH_C) + CommonConstant.SLASH + genClass + "SaveDTO.java");
        map.put(VO, moduleName + JAVA_PATH + javaFilePackageMap.get(VO).replace(CommonConstant.PERIOD_C, CommonConstant.SLASH_C) + CommonConstant.SLASH + genClass + "VO.java");
        map.put(MAPPER_XML, moduleName + RESOURCES_PATH + "mapper" + CommonConstant.SLASH + genClass + "Mapper.xml");
        map.put(INDEX_VUE, VUE_PATH + (StrUtil.isNotBlank(genModule) ? genModule : "") + CommonConstant.SLASH + genBusiness + CommonConstant.SLASH + "index.vue");
        map.put(SAVE_VUE, VUE_PATH + (StrUtil.isNotBlank(genModule) ? genModule : "") + CommonConstant.SLASH + genBusiness + CommonConstant.SLASH + "save.vue");
        map.put(JS, JS_PATH + (StrUtil.isNotBlank(genModule) ? genModule : "") + CommonConstant.SLASH + genBusiness + ".js");
        map.put(SQL, "sql" + CommonConstant.SLASH + genBusiness + ".sql");
        return map;
    }

    /**
     * zip文件相对路径
     */
    public static Map<String, String> zipFileRelativePath(String projectCode, String genPackage, String genModule, String genClass, String genClassName, String genBusiness) {
        Map<String, String> fileRelativePath = fileRelativePath(projectCode, genPackage, genModule, genClass, genClassName, genBusiness);

        Map<String, String> map = new HashMap<>();
        map.put(ENTITY, "backend" + CommonConstant.SLASH + fileRelativePath.get(ENTITY));
        map.put(CONTROLLER, "backend" + CommonConstant.SLASH + fileRelativePath.get(CONTROLLER));
        map.put(SERVICE, "backend" + CommonConstant.SLASH + fileRelativePath.get(SERVICE));
        map.put(SERVICE_IMPL, "backend" + CommonConstant.SLASH + fileRelativePath.get(SERVICE_IMPL));
        map.put(MAPPER, "backend" + CommonConstant.SLASH + fileRelativePath.get(MAPPER));
        map.put(QUERY_DTO, "backend" + CommonConstant.SLASH + fileRelativePath.get(QUERY_DTO));
        map.put(SAVE_DTO, "backend" + CommonConstant.SLASH + fileRelativePath.get(SAVE_DTO));
        map.put(VO, "backend" + CommonConstant.SLASH + fileRelativePath.get(VO));
        map.put(MAPPER_XML, "backend" + CommonConstant.SLASH + fileRelativePath.get(MAPPER_XML));
        map.put(INDEX_VUE, "front" + CommonConstant.SLASH + fileRelativePath.get(INDEX_VUE));
        map.put(SAVE_VUE, "front" + CommonConstant.SLASH + fileRelativePath.get(SAVE_VUE));
        map.put(JS, "front" + CommonConstant.SLASH + fileRelativePath.get(JS));
        map.put(SQL, "backend" + CommonConstant.SLASH + fileRelativePath.get(SQL));
        return map;
    }

    /**
     * 文件生成路径
     */
    public static Map<String, String> filePath(String projectCode, String genPackage, String genModule, String genClass, String genClassName, String genBusiness, String genBackendPath, String genFrontPath) {
        Map<String, String> fileRelativePath = fileRelativePath(projectCode, genPackage, genModule, genClass, genClassName, genBusiness);

        String backendPath = genBackendPath + (genBackendPath.endsWith(CommonConstant.SLASH) ? "" : CommonConstant.SLASH);
        String frontPath = genFrontPath + (genFrontPath.endsWith(CommonConstant.SLASH) ? "" : CommonConstant.SLASH);

        Map<String, String> map = new HashMap<>();
        map.put(ENTITY, backendPath + fileRelativePath.get(ENTITY));
        map.put(CONTROLLER, backendPath + fileRelativePath.get(CONTROLLER));
        map.put(SERVICE, backendPath + fileRelativePath.get(SERVICE));
        map.put(SERVICE_IMPL, backendPath + fileRelativePath.get(SERVICE_IMPL));
        map.put(MAPPER, backendPath + fileRelativePath.get(MAPPER));
        map.put(QUERY_DTO, backendPath + fileRelativePath.get(QUERY_DTO));
        map.put(SAVE_DTO, backendPath + fileRelativePath.get(SAVE_DTO));
        map.put(VO, backendPath + fileRelativePath.get(VO));
        map.put(MAPPER_XML, backendPath + fileRelativePath.get(MAPPER_XML));
        map.put(INDEX_VUE, frontPath + fileRelativePath.get(INDEX_VUE));
        map.put(SAVE_VUE, frontPath + fileRelativePath.get(SAVE_VUE));
        map.put(JS, frontPath + fileRelativePath.get(JS));
        map.put(SQL, backendPath + fileRelativePath.get(SQL));
        return map;
    }

}
